import json
import time
import sys
import os
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
from argparse import ArgumentParser
from .api import APIClient, APIError

store_file = os.path.expanduser('~/.zoomeye')


def do_resource_cmd(args, parser):
    if args.username is None:
        parser.error('use [-u] to specify an username, or use [zoomeye setuser] to set default user')
    if args.password is None:
        parser.error('use [-p] to specify a password, or use [zoomeye setuser] to set default user')
    client = APIClient()
    try:
        client.login(args.username, args.password)
        print json.dumps(client.resources_info())
    except APIError, e:
        sys.stderr.write(e.message + "\n")
        sys.exit(-1)


def export(args):
    client = APIClient()
    client.login(args.username, args.password)
    page = max_page = args.start_page
    while page <= max_page:
        if args.web:
            result = client.query_web(query=args.query, app=args.app, header=args.header, keywords=args.keywords,
                                      desc=args.desc, title=args.title, ip=args.ip, site=args.site, city=args.city,
                                      country=args.country, page=page)
        else:
            result = client.query_host(query=args.query, app=args.app, version=args.ver, device=args.device, os=args.os,
                                       service=args.service, ip=args.ip, cidr=args.cidr, hostname=args.hostname,
                                       port=args.port, city=args.city, country=args.country, asn=args.asn,
                                       page=page)
        data_set = result['matches']
        total = result['total']
        if len(data_set) == 0:
            break
        max_page = total / len(data_set) + 1
        for data in data_set:
            yield json.dumps(data)
        page += 1
        if args.interval > 0:
            time.sleep(args.interval)


def do_export_cmd(args, parser):
    if args.username is None:
        parser.error('use [-u] to specify an username, or use [zoomeye setuser] to set default user')
    if args.password is None:
        parser.error('use [-p] to specify a password, or use [zoomeye setuser] to set default user')
    try:
        if args.output == '-':
            for data in export(args):
                print data
        else:
            with open(os.path.expanduser(args.output), 'wb') as f:
                for data in export(args):
                    f.write(data + '\n')
    except APIError, e:
        sys.stderr.write(e.message + "\n")
        sys.exit(-1)


def do_setuser_cmd(args, parser):
    with open(store_file, 'wb') as f:
        f.write('[account]\n')
    conf = ConfigParser()
    with open(store_file, 'rb') as f:
        conf.readfp(f)
    conf.set('account', 'username', args.username)
    conf.set('account', 'password', args.password)
    with open(store_file, 'wb') as f:
        conf.write(f)


def get_default_user():
    if os.path.exists(store_file):
        conf = ConfigParser()
        with open(store_file, 'rb') as f:
            conf.readfp(f)
        try:
            return conf.get('account', 'username'), conf.get('account', 'password')
        except NoSectionError:
            pass
        except NoOptionError:
            pass
    return None, None


def get_args():
    username, password = get_default_user()
    parser = ArgumentParser(version="1.0")
    subparsers = parser.add_subparsers()
    subparsers.required = True
    parser_resource = subparsers.add_parser('resource', help='resources info for account', version='1.0')
    parser_resource.add_argument('-u', '--username', help="username, default [%s]" % username, default=username)
    parser_resource.add_argument('-p', '--password', help="password, default [%s]" % password, default=password)
    parser_resource.set_defaults(func=do_resource_cmd)

    parser_export = subparsers.add_parser('export', help='export query data', version='1.0',
                                          description="Export data from zoomeye.org by giving query string")
    parser_export.add_argument('-u', '--username', help="username, default [%s]" % username, default=username)
    parser_export.add_argument('-p', '--password', help="password, default [%s]" % password, default=password)
    filter_group = parser_export.add_argument_group("search filters")
    filter_group.add_argument('-q', '--query', help="set original query string. Example: [app:ProFTD]")
    filter_group.add_argument('--app', help="filter host or web result with app, such as [ProFTD]")
    filter_group.add_argument('--ver', help="filter host result with version, such as [2.1]")
    filter_group.add_argument('--device', help="filter host result with device, such as [router]")
    filter_group.add_argument('--os', help="filter host result with os, such as [windows]")
    filter_group.add_argument('--service', help="filter host result with service, such as [http]")
    filter_group.add_argument('--ip', help="filter host or web result with ip, such as [192.168.1.1]")
    filter_group.add_argument('--cidr', help="filter host result with cidr, such as [192.168.1.1/24]")
    filter_group.add_argument('--hostname', help="filter host result with hostname, such as [google.com]")
    filter_group.add_argument('--port', help="filter host result with port, such as [80]", type=int)
    filter_group.add_argument('--city', help="filter host or web result with city, such as [beijing]")
    filter_group.add_argument('--country', help="filter host or web result with country, such as [china]")
    filter_group.add_argument('--asn', help="filter host result with asn, such as [AS8978]")
    filter_group.add_argument('--header', help="filter web result with header, such as [server]")
    filter_group.add_argument('--keywords', help="filter web result with meta keywords")
    filter_group.add_argument('--desc', help="filter web result with HTTP meta description")
    filter_group.add_argument('--title', help="filter web result with title, such as [Google]")
    filter_group.add_argument('--site', help="filter web result with site, such as [www.google.com]")

    parser_export.add_argument('-i', '--interval', default=0, type=int,
                               help="set interval time for each query, default 0 second")
    parser_export.add_argument('-o', '--output', help="set output file. [-] represents stdout, default [-]",
                               default='-')
    parser_export.add_argument('-s', '--start-page', default=1, type=int, help="set start page, default [1]")
    group = parser_export.add_mutually_exclusive_group()
    group.add_argument('--host', action='store_true', default=True, help="search host, this option is default")
    group.add_argument('--web', action='store_true', default=False, help="search website")

    parser_setuser = subparsers.add_parser('setuser', help='set default username and password', version='1.0',
                                           description="set username and password as default")
    parser_setuser.add_argument('username', help="username")
    parser_setuser.add_argument('password', help="password")
    parser_setuser.set_defaults(func=do_setuser_cmd)

    parser_export.set_defaults(func=do_export_cmd)

    args = parser.parse_args()
    args.func(args, parser)


def main():
    try:
        get_args()
    except KeyboardInterrupt:
        pass


if __name__ == '__main__':
    main()
